package butines.core.gui;
/*
import static java.awt.event.KeyEvent.VK_DOWN;
import static java.awt.event.KeyEvent.VK_ENTER;
import static java.awt.event.KeyEvent.VK_UP;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;

import butines.core.GameCore;
import butines.core.GameFont;
import butines.core.Mouse;

public class GUIConsole extends GUIComponent implements KeyListener {

	/**
	 * Maximum amount of verbose data kept in the console also the number of
	 * lines of data displayed
	 * /
	public static final int MAX_LINES = 10;

	public static final int xOffset = 4;
	public static final int yOffset = 2;
	
	public HashMap<String, Command> commands = new HashMap<String, Command>();

	private LinkedList<String> lastMessages = new LinkedList<String>();

	private Color backgroundColor = new Color(0, 0, 0, .5f);

	private boolean open;

	private GameCore gameCore;
	private GameFont font;

	private Command help;
	private Command auto;
	
	private GUIFieldText inputCommand;
	
	private static final int MAX_INPUT_BUFFER = 20;

	private String input;
	private boolean completedInput;
	private LinkedList<String> lastInputs = new LinkedList<String>();
	private int idxLastInput;
	
	public GUIConsole(GameCore gameCore) {
		this.gameCore = gameCore;
		this.font = gameCore.getDefaultFont();

		int lineHeight = font.getLineHeight();
		int consoleHeight = (MAX_LINES * lineHeight) - yOffset;

		inputCommand = new GUIFieldText(font, xOffset, consoleHeight);
	}
	
	public GameCore getGameCore() {
		return gameCore;
	}

	public Command getHelp() {
		return help;
	}

	public void setHelp(Command help) {
		if (help != null) {
			removeCommand(help);
		}
		this.help = help;
		if (help != null) {
			addCommand(help);
		}
	}

	public Command getAuto() {
		return auto;
	}

	public void setAuto(Command auto) {
		if (auto != null) {
			removeCommand(auto);
		}
		this.auto = auto;
		if (auto != null) {
			addCommand(auto);
		}
	}

	public void addCommand(Command cmd) {
		commands.put(cmd.getName(), cmd);
	}
	
	public void removeCommand(Command cmd) {
		commands.remove(cmd.getName());
	}
	public Collection<Command> getCommands() {
		return commands.values();
	}
	
	public void log(String s) {
		if (s == null) {
			return;
		}

		if (lastMessages.size() + 1 > MAX_LINES) {
			lastMessages.removeLast();
		}

		lastMessages.addFirst(s);
	}

	private void close() {
		open = false;
	}

	private void open() {
		open = true;
		inputCommand.clear();
		idxLastInput = -1;
	}

	public void toggle() {
		if (open) {
			close();
		} else {
			open();
		}
	}

	public boolean isOpen() {
		return open;
	}

	@Override
	public void renderComponent(Graphics2D g2d) {
		if (open == false) {
			return;
		}
		int lineHeight = font.getLineHeight();
		int consoleHeight = (MAX_LINES + 1) * lineHeight + yOffset; // +1 for the input line

		g2d.setColor(backgroundColor);
		g2d.fillRect(0, 0, gameCore.getWidth(), consoleHeight);

		inputCommand.render(g2d);
		
		consoleHeight -= lineHeight;
		
		// draws bottom up starting with typing
		for (int i = 0; i < lastMessages.size(); i++) {
			String str = lastMessages.get(i);
			font.render(g2d, xOffset, (consoleHeight -= lineHeight + 2), str);
			// and then the verbose data in order of newest first
		}
		
	}

	@Override
	public void updateComponent(Mouse mouse) {
		if (completedInput) {
			processInput(input);
			completedInput = false;
		}
	}

	
	private void addLastInput(String input) {
		while (lastInputs.size() >= MAX_INPUT_BUFFER) {
			lastInputs.removeLast();
		}
		lastInputs.addFirst(input);
	}
	
	// implements KeyListener
	@Override
	public void keyTyped(KeyEvent e) {
		if (open) {
			inputCommand.keyTyped(e);
		}
	}

	@Override
	public void keyPressed(KeyEvent e) {
		if (open) {
			inputCommand.keyPressed(e);
			
			if (e.getKeyCode() == VK_UP) {
				if (idxLastInput < lastInputs.size() - 1) {
					inputCommand.setText(lastInputs.get(++idxLastInput));
				}
			}
			
			if (e.getKeyCode() == VK_DOWN) {
				if (idxLastInput > 0) {
					inputCommand.setText(lastInputs.get(--idxLastInput));
				}
			}
			
		}
	}

	@Override
	public void keyReleased(KeyEvent e) {
		if (open) {
			inputCommand.keyReleased(e);
			
			if (e.getKeyCode() == VK_ENTER) {
				String str = inputCommand.getText();
				if (str.length() > 0) {
					addLastInput(input = str);
					completedInput = true;
					inputCommand.clear();
					idxLastInput = -1;
				}
			}
			
		}
	}
	
	// Execute command //
	
	private String[] createArgs(String cmdArgs, int numberOfArgs) {	
		if (numberOfArgs == -1) {
			return new String[] { cmdArgs };
		}
		
		if (numberOfArgs <= 0) {
			return null;
		}
		
		cmdArgs = cmdArgs.replaceAll("\\s+", " ");

		String[] arr  = cmdArgs.split(" ");
		String[] args = new String[numberOfArgs];
		
		for (int i = 0; i < numberOfArgs; i++) {
			args[i] = arr[i];
		}
		
		return args;
	}
	
	private boolean execute(Command cmd, String cmdArgs) {
		if (cmd != null) {
			String[] args = createArgs(cmdArgs, cmd.getNumberOfArgs());
			cmd.execute(this, args);
			return true;
		}
		return false;
	}
	
	private void processInput(String input) {
		
		log(">" + input);
		
		String[] cmdAndArgs = input.split(" ", 2);

		String cmdName = cmdAndArgs[0].trim();
		String cmdArgs = (cmdAndArgs.length == 2) ? cmdAndArgs[1] : "";
		
		cmdArgs = cmdArgs.trim();
		
		if (cmdName.startsWith("/")) {
			cmdName = cmdName.substring(1);
			Command cmd = commands.get(cmdName);
			if (cmd == null) {			
				log("ERROR: Command " + input + " not found!");
				if (help != null) {
					log("For help: /" + help.getName());
				}
			} else {
				execute(cmd, cmdArgs);
			}
		} else if (auto != null) {
			execute(auto, input);
		}
		
	}

	public abstract class Command {

		private String name;
		private String helpMessage;
		private int numberOfArgs; // -1 args means return raw input data minus the command

		public Command(String name, int numberOfArgs, String helpMessage) {
			this.name = name;
			this.numberOfArgs = numberOfArgs;
			this.helpMessage = helpMessage;
		}

		public String getName() {
			return name;
		}

		public String getHelpMessage() {
			return helpMessage;
		}

		public int getNumberOfArgs() {
			return numberOfArgs;
		}

		public abstract void execute(GUIConsole console, String ... args);

	}
	
}*/